#include "message.h"
#include "timeStamp.h"
#include <sstream>
#include <iostream>


//格式化日志头部的颜色(色号，颜色深浅，不同字段之间的分隔符，要格式化的字段，是否上色)
//日志的头部：[时间戳][日志级别][文件名称][函数名称][行号]，一个[xx]就是一个字段
 //该函数就是对这一句的拼接
        //printf("\033[0;35m helloworld\n");浅色
        //printf("\033[1;35m helloworld\n");深色
std::string Message::formatFieldWithColor(COLOR_NUMBER colorNumber, bool dark, 
    const std::string& delimiter, const std::string& fieldName, bool colored) {
    std::stringstream ss;
    if (colored) {
        ss << "\033[" << dark << ";" <<colorNumber << "m";
    }
    ss << fieldName;
    if (colored) {
        ss << "\033[0m";    //<这样就使颜色回归白色，不至于使后面所有字段都是一个颜色
    }
    ss << delimiter;
    return ss.str();
}


Message::Message(LOG_LEVEL level, const std::string& absoluteFileName,
    const std::string& functionName, int lineNumber){
    //fileName由于获取的文件名字有点长，还包含了路径。这里只取最后一个/之后的文件名
    //[/home/ubuntu/mytest/src/utils/tcpServer.cc]  ->  [tcpServer.cc]
    std::string fileName = absoluteFileName;
    int pos = 0;
    for (int i = fileName.length() - 1; i > 0; --i) {
        if (fileName[i] == '/') {
            pos = i;
            break;
        }
    }
    fileName = fileName.substr(pos + 1, fileName.length() - pos);

    m_coloredHeader = FormatHeader(level, fileName, functionName, lineNumber, true);
    m_commonHeader = FormatHeader(level, fileName, functionName, lineNumber, false);
}

//格式化日志头部
//日志的头部：[时间戳][日志级别][文件名称][函数名称][行号]，一个[xx]就是一个字段
std::string Message::FormatHeader(LOG_LEVEL level, const std::string& fileName,
    const std::string& functionName, int lineNumber, bool colored){
    //时间戳
    std::stringstream ss;
    ss << formatFieldWithColor(DEFAULT_COLOR, 0, "", TimeStamp::Now().ToString(), colored);

    //日志级别  INFO -> "[INFO]"
    COLOR_NUMBER logColorNumber = logLevelColor[level];
    std::string logLevel = logLevelTypeString[level];
    ss << formatFieldWithColor(logColorNumber, 1, "", logLevel, colored);

    //文件名称
    COLOR_NUMBER fileColor = logFeildColor[FILE_NAME];
    ss << formatFieldWithColor(fileColor, 1, "", "[" + fileName + "]", colored);

    //函数名称
    COLOR_NUMBER functionColor = logFeildColor[FUNCTION_NAME];
    ss << formatFieldWithColor(functionColor, 1, "", "[" +functionName + "]", colored);

    //行号
    COLOR_NUMBER lineColor = logFeildColor[LINE_NUMBER];
    ss << formatFieldWithColor(lineColor, 1, " : ", "[" +std::to_string(lineNumber) + "]", colored);

    return ss.str();
}

std::string Message::ToString(bool colored) const
{
    return colored ? m_coloredHeader + m_msg : m_commonHeader + m_msg;
    //                            上色+输出m_msg         不上色+输出m_msg
}





// int main() {
//     Message msg1(INFO, __FILE__, __FUNCTION__, __LINE__ );
//      Message msg2(ERROR, __FILE__, __FUNCTION__, __LINE__ );
//       Message msg3(DEBUG, __FILE__, __FUNCTION__, __LINE__ );
//        Message msg4(FATAL, __FILE__, __FUNCTION__, __LINE__ );

//     msg1<<"hello1";
//     msg2<<"hello2";
//     msg3<<"hello3";
//     msg4<<"hello4";

//     std::cout << msg1.ToString() << std::endl;
//     std::cout << msg2.ToString() << std::endl;
//     std::cout << msg3.ToString() << std::endl;
//     std::cout << msg4.ToString() << std::endl;

//     return 0;
// }